home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Software Money Savers / VirtualDub / Source / VirtualDub-1.7.7-src.7z / src / h / vd2 / system / int128.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-14  |  8.3 KB  |  355 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #ifndef f_VD2_SYSTEM_INT128_H
  27. #define f_VD2_SYSTEM_INT128_H
  28.  
  29. #include <vd2/system/vdtypes.h>
  30.  
  31. struct vdint128;
  32. struct vduint128;
  33.  
  34. #ifdef _M_AMD64
  35.     extern "C" __int64 _mul128(__int64 x, __int64 y, __int64 *hiresult);
  36.     extern "C" unsigned __int64 _umul128(unsigned __int64 x, unsigned __int64 y, unsigned __int64 *hiresult);
  37.     extern "C" unsigned __int64 __shiftleft128(unsigned __int64 low, unsigned __int64 high, unsigned char shift);
  38.     extern "C" unsigned __int64 __shiftright128(unsigned __int64 low, unsigned __int64 high, unsigned char shift);
  39.  
  40.     #pragma intrinsic(_mul128)
  41.     #pragma intrinsic(_umul128)
  42.     #pragma intrinsic(__shiftleft128)
  43.     #pragma intrinsic(__shiftright128)
  44.  
  45.     extern "C" {
  46.         void vdasm_uint128_add(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  47.         void vdasm_uint128_sub(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  48.         void vdasm_uint128_mul(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  49.     }
  50. #else
  51.     extern "C" {
  52.         void __cdecl vdasm_uint128_add(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  53.         void __cdecl vdasm_uint128_sub(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  54.     }
  55. #endif
  56.  
  57. struct vdint128 {
  58. public:
  59.     union {
  60.         sint32 d[4];
  61.         sint64 q[2];
  62.     };
  63.  
  64.     vdint128() {}
  65.  
  66.     vdint128(sint64 x) {
  67.         q[0] = x;
  68.         q[1] = x>>63;
  69.     }
  70.  
  71.     vdint128(uint64 x) {
  72.         q[0] = (sint64)x;
  73.         q[1] = 0;
  74.     }
  75.  
  76.     vdint128(int x) {
  77.         q[0] = x;
  78.         q[1] = (sint64)x >> 63;
  79.     }
  80.  
  81.     vdint128(unsigned int x) {
  82.         q[0] = x;
  83.         q[1] = 0;
  84.     }
  85.  
  86.     vdint128(unsigned long x) {
  87.         q[0] = x;
  88.         q[1] = 0;
  89.     }
  90.  
  91.     sint64 getHi() const { return q[1]; }
  92.     uint64 getLo() const { return q[0]; }
  93.  
  94.     operator double() const;
  95.     operator sint64() const {
  96.         return (sint64)q[0];
  97.     }
  98.     operator uint64() const {
  99.         return (uint64)q[0];
  100.     }
  101.  
  102.     bool operator==(const vdint128& x) const {
  103.         return q[1] == x.q[1] && q[0] == x.q[0];
  104.     }
  105.  
  106.     bool operator!=(const vdint128& x) const {
  107.         return q[1] != x.q[1] || q[0] != x.q[0];
  108.     }
  109.  
  110.     bool operator<(const vdint128& x) const {
  111.         return q[1] < x.q[1] || (q[1] == x.q[1] && (uint64)q[0] < (uint64)x.q[0]);
  112.     }
  113.  
  114.     bool operator<=(const vdint128& x) const {
  115.         return q[1] < x.q[1] || (q[1] == x.q[1] && (uint64)q[0] <= (uint64)x.q[0]);
  116.     }
  117.  
  118.     bool operator>(const vdint128& x) const {
  119.         return q[1] > x.q[1] || (q[1] == x.q[1] && (uint64)q[0] > (uint64)x.q[0]);
  120.     }
  121.  
  122.     bool operator>=(const vdint128& x) const {
  123.         return q[1] > x.q[1] || (q[1] == x.q[1] && (uint64)q[0] >= (uint64)x.q[0]);
  124.     }
  125.  
  126.     const vdint128 operator+(const vdint128& x) const {
  127.         vdint128 t;
  128.         vdasm_uint128_add((uint64 *)t.q, (const uint64 *)q, (const uint64 *)x.q);
  129.         return t;
  130.     }
  131.  
  132.     const vdint128 operator-(const vdint128& x) const {
  133.         vdint128 t;
  134.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)q, (const uint64 *)x.q);
  135.         return t;
  136.     }
  137.  
  138.     const vdint128& operator+=(const vdint128& x) {
  139.         vdasm_uint128_add((uint64 *)q, (const uint64 *)q, (const uint64 *)x.q);
  140.         return *this;
  141.     }
  142.  
  143.     const vdint128& operator-=(const vdint128& x) {
  144.         vdasm_uint128_sub((uint64 *)q, (const uint64 *)q, (const uint64 *)x.q);
  145.         return *this;
  146.     }
  147.  
  148.     const vdint128 operator*(const vdint128& x) const;
  149.  
  150.     const vdint128 operator-() const {
  151.         vdint128 t(0);
  152.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)t.q, (const uint64 *)q);
  153.         return t;
  154.     }
  155.  
  156.     const vdint128 abs() const {
  157.         return q[1] < 0 ? -*this : *this;
  158.     }
  159.  
  160. #ifdef _M_AMD64
  161.     void setSquare(sint64 v) {
  162.         const vdint128 v128(v);
  163.         operator=(v128*v128);
  164.     }
  165.  
  166.     const vdint128 operator<<(int count) const {
  167.         vdint128 t;
  168.  
  169.         if (count >= 64) {
  170.             t.q[0] = 0;
  171.             t.q[1] = q[0] << (count-64);
  172.         } else {
  173.             t.q[0] = q[0] << count;
  174.             t.q[1] = __shiftleft128(q[0], q[1], count);
  175.         }
  176.  
  177.         return t;
  178.     }
  179.  
  180.     const vdint128 operator>>(int count) const {
  181.         vdint128 t;
  182.  
  183.         if (count >= 64) {
  184.             t.q[0] = q[1] >> (count-64);
  185.             t.q[1] = q[1] >> 63;
  186.         } else {
  187.             t.q[0] = __shiftright128(q[0], q[1], count);
  188.             t.q[1] = q[1] >> count;
  189.         }
  190.  
  191.         return t;
  192.     }
  193. #else
  194.     void setSquare(sint64 v);
  195.  
  196.     const vdint128 operator<<(int v) const;
  197.     const vdint128 operator>>(int v) const;
  198. #endif
  199. };
  200.  
  201. struct vduint128 {
  202. public:
  203.     union {
  204.         uint32 d[4];
  205.         uint64 q[2];
  206.     };
  207.  
  208.     vduint128() {}
  209.  
  210.     vduint128(sint64 x) {
  211.         q[0] = (sint64)x;
  212.         q[1] = 0;
  213.     }
  214.  
  215.     vduint128(uint64 x) {
  216.         q[0] = x;
  217.         q[1] = 0;
  218.     }
  219.  
  220.     vduint128(int x) {
  221.         q[0] = (uint64)x;
  222.         q[1] = 0;
  223.     }
  224.  
  225.     vduint128(unsigned x) {
  226.         q[0] = x;
  227.         q[1] = 0;
  228.     }
  229.  
  230.     vduint128(uint64 hi, uint64 lo) {
  231.         q[0] = lo;
  232.         q[1] = hi;
  233.     }
  234.  
  235.     uint64 getHi() const { return q[1]; }
  236.     uint64 getLo() const { return q[0]; }
  237.  
  238.     operator sint64() const {
  239.         return (sint64)q[0];
  240.     }
  241.  
  242.     operator uint64() const {
  243.         return (uint64)q[0];
  244.     }
  245.  
  246.     bool operator==(const vduint128& x) const {
  247.         return q[1] == x.q[1] && q[0] == x.q[0];
  248.     }
  249.  
  250.     bool operator!=(const vduint128& x) const {
  251.         return q[1] != x.q[1] || q[0] != x.q[0];
  252.     }
  253.  
  254.     bool operator<(const vduint128& x) const {
  255.         return q[1] < x.q[1] || (q[1] == x.q[1] && q[0] < x.q[0]);
  256.     }
  257.  
  258.     bool operator<=(const vduint128& x) const {
  259.         return q[1] < x.q[1] || (q[1] == x.q[1] && q[0] <= x.q[0]);
  260.     }
  261.  
  262.     bool operator>(const vduint128& x) const {
  263.         return q[1] > x.q[1] || (q[1] == x.q[1] && q[0] > x.q[0]);
  264.     }
  265.  
  266.     bool operator>=(const vduint128& x) const {
  267.         return q[1] > x.q[1] || (q[1] == x.q[1] && q[0] >= x.q[0]);
  268.     }
  269.  
  270.     const vduint128 operator+(const vduint128& x) const {
  271.         vduint128 t;
  272.         vdasm_uint128_add(t.q, q, x.q);
  273.         return t;
  274.     }
  275.  
  276.     const vduint128 operator-(const vduint128& x) const {
  277.         vduint128 t;
  278.         vdasm_uint128_sub(t.q, q, x.q);
  279.         return t;
  280.     }
  281.  
  282.     const vduint128& operator+=(const vduint128& x) {
  283.         vdasm_uint128_add(q, q, x.q);
  284.         return *this;
  285.     }
  286.  
  287.     const vduint128& operator-=(const vduint128& x) {
  288.         vdasm_uint128_sub(q, q, x.q);
  289.         return *this;
  290.     }
  291.  
  292.     const vduint128 operator*(const vduint128& x) const;
  293.  
  294.     const vduint128 operator-() const {
  295.         vduint128 t(0U);
  296.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)t.q, (const uint64 *)q);
  297.         return t;
  298.     }
  299.  
  300.     vduint128& operator<<=(int count) {
  301.         return operator=(operator<<(count));
  302.     }
  303.  
  304.     vduint128& operator>>=(int count) {
  305.         return operator=(operator>>(count));
  306.     }
  307.  
  308. #ifdef _M_AMD64
  309.     const vduint128 operator<<(int count) const {
  310.         vduint128 t;
  311.  
  312.         if (count >= 64) {
  313.             t.q[0] = 0;
  314.             t.q[1] = q[0] << (count-64);
  315.         } else {
  316.             t.q[0] = q[0] << count;
  317.             t.q[1] = __shiftleft128(q[0], q[1], count);
  318.         }
  319.  
  320.         return t;
  321.     }
  322.  
  323.     const vduint128 operator>>(int count) const {
  324.         vduint128 t;
  325.  
  326.         if (count >= 64) {
  327.             t.q[0] = q[1] >> (count-64);
  328.             t.q[1] = 0;
  329.         } else {
  330.             t.q[0] = __shiftright128(q[0], q[1], count);
  331.             t.q[1] = q[1] >> count;
  332.         }
  333.  
  334.         return t;
  335.     }
  336. #else
  337.     const vduint128 operator<<(int v) const;
  338.     const vduint128 operator>>(int v) const;
  339. #endif
  340. };
  341.  
  342. #ifdef _M_AMD64
  343.     inline vduint128 VDUMul64x64To128(uint64 x, uint64 y) {
  344.         vduint128 result;
  345.         result.q[0] = _umul128(x, y, &result.q[1]);
  346.         return result;
  347.     }
  348.     uint64 VDUDiv128x64To64(const vduint128& dividend, uint64 divisor, uint64& remainder);
  349. #else
  350.     vduint128 VDUMul64x64To128(uint64 x, uint64 y);
  351.     uint64 VDUDiv128x64To64(const vduint128& dividend, uint64 divisor, uint64& remainder);
  352. #endif
  353.  
  354. #endif
  355.